home *** CD-ROM | disk | FTP | other *** search
/ Aminet 23 / Aminet 23 (1998)(GTI - Schatztruhe)[!][Feb 1998].iso / Aminet / comm / net / AMarquee1_46.lha / AMarquee / examples / MiniIRC.c < prev    next >
C/C++ Source or Header  |  1997-12-06  |  6KB  |  202 lines

  1.  
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <stdlib.h>
  5.  
  6. #include <dos/dos.h>
  7. #include <clib/dos_protos.h>
  8. #include <clib/exec_protos.h>
  9.  
  10. #include <clib/AMarquee_protos.h>
  11. #include <pragmas/AMarquee_pragmas.h>
  12.  
  13. #define UNLESS(x) if(!(x))
  14.  
  15. struct Library * AMarqueeBase = NULL;
  16. struct QSession * session     = NULL;
  17.  
  18. void CleanExit(void)
  19. {
  20.   if (session)      QFreeSession(session);       /* This MUST be done before we close the library! */
  21.   if (AMarqueeBase) CloseLibrary(AMarqueeBase);
  22.   printf("Program complete.\n");
  23. }
  24.  
  25. /* Parses out the nth section of the given path string.  
  26.    May write a NUL to the string to terminate the part, but with 
  27.    amarquee.library that's okay behavior. */
  28. char * GetNthPart(char * path, int n)
  29. {
  30.   char * temp = path;
  31.   
  32.   while((n--)>0)
  33.   { 
  34.     temp++; path = temp;
  35.     UNLESS(temp = strchr(temp, '/')) return(path);
  36.   }
  37.   *temp = '\0';
  38.   return(path);
  39. }
  40.  
  41. /* There is a problem in this function:  any "regular" update
  42.    messages that arrive while this function is waiting for info
  43.    will be silently thrown away.  This should be fixed but I'm
  44.    too lazy!  :P  */
  45. /* Returns TRUE on completion, FALSE on error */
  46. BOOL ListPeopleInRoom(void)
  47. {
  48.   int getop  = QGetOp(session, "/#?/mini_irc_#?", 0);
  49.   int pingop = QPingOp(session);
  50.   int retVal = -1;
  51.   ULONG signals = (1L << session->qMsgPort->mp_SigBit) | (SIGBREAKF_CTRL_C);
  52.     
  53.   UNLESS((getop)&&(pingop)&&(QGo(session,0L))) return(FALSE);
  54.   
  55.   /* Now wait for data to come back! */
  56.   printf("People currently in the room:--------\n");
  57.  
  58.   /* Wait for next message from the server */
  59.   while(retVal == -1)
  60.   {
  61.     signals = Wait(signals);
  62.     
  63.     if (signals & (1L << session->qMsgPort->mp_SigBit))
  64.     {
  65.       struct QMessage * qMsg;
  66.             
  67.       while((retVal == -1)&&(qMsg = (struct QMessage *) GetMsg(session->qMsgPort)))
  68.       {
  69.         if (qMsg->qm_Status != QERROR_NO_ERROR) 
  70.         {
  71.           printf("-->Error %i detected, exiting!\n", qMsg->qm_Status);
  72.           retVal = FALSE;
  73.         }
  74.         else
  75.         {
  76.           char * name = qMsg->qm_Path ? (GetNthPart(qMsg->qm_Path, 2)+sizeof("mini_irc_")-1) : "<unknown?>";
  77.           
  78.           if (qMsg->qm_ID == getop) printf("  %s\n",name);
  79.           if (qMsg->qm_ID == pingop) retVal = TRUE;  /* we're done! */
  80.         }
  81.         FreeQMessage(session,qMsg);
  82.       }
  83.     }
  84.     if (signals & SIGBREAKF_CTRL_C) retVal = FALSE;
  85.   }
  86.   printf("---------End of people list----------\n");
  87.   return(retVal);
  88. }
  89.  
  90.  
  91. /* Main program--simply increments our counter whenever someone else increments theirs */
  92. int main(int argc, char ** argv)
  93. {
  94.   char * connectTo, * username;
  95.   int port = 2957;
  96.   int clientOp, actionOp, talkOp;
  97.   char buf[900];
  98.   
  99.   atexit(CleanExit);
  100.    
  101.   printf("Usage Note:  MiniIRC [hostname=localhost] [nickname=$LOGNAME]\n");
  102.   
  103.   connectTo = (argc > 1) ? argv[1] : "localhost";
  104.   username =  (argc > 2) ? argv[2] : NULL;
  105.   
  106.   /* Try a few guesses here! */
  107.   if (username == NULL) username = getenv("logname");
  108.   if (username == NULL) username = getenv("user");
  109.   if (username == NULL) username = getenv("username");
  110.   if (username == NULL) username = "unknown";
  111.   
  112.   UNLESS(AMarqueeBase = OpenLibrary("amarquee.library",37L))
  113.   {
  114.     printf("Couldn't open amarquee.library v37!\n");
  115.     exit(RETURN_ERROR);
  116.   }
  117.   printf("Connecting to %s:%i...\n",connectTo, port);
  118.   sprintf(buf, "mini_irc_%s",username);
  119.   UNLESS(session = QNewSession(connectTo, port, buf))
  120.   {
  121.     printf("Couldn't connect to server %s:%i\n",connectTo, port);
  122.     CloseLibrary(AMarqueeBase);
  123.     exit(RETURN_WARN);
  124.   }
  125.   
  126.   printf("MiniIRC: connected to server %s:%i as %s.\n", connectTo, port, username);
  127.  
  128.   /* Setup--put in our interests!  */
  129.   UNLESS((clientOp = QSubscribeOp(session, "/#?/mini_irc_#?",        0))   &&
  130.          (actionOp = QSubscribeOp(session, "/#?/mini_irc_#?/action", 900)) &&
  131.          (talkOp   = QSubscribeOp(session, "/#?/mini_irc_#?/talk",   900)) &&
  132.          (QGo(session,0L)))
  133.   {
  134.     printf("-->error setting up!\n");
  135.     exit(5);
  136.   }
  137.          
  138.   printf("Press CTRL-D when you wish to do something, or\n");
  139.   printf("Press CTRL-E to list the names of everyone in the room.\n");
  140.   printf("Press CTRL-F when you wish to say something!\n");
  141.   printf("Press CTRL-C to quit.\n");
  142.   printf("==============================================\n");  
  143.   
  144.   Signal(FindTask(NULL), SIGBREAKF_CTRL_E);  /* cause an immediate listing of who is in the room */
  145.   
  146.   while(1)
  147.   {
  148.     struct QMessage * qMsg;
  149.     ULONG signals = (1L << session->qMsgPort->mp_SigBit) | (SIGBREAKF_CTRL_C) | (SIGBREAKF_CTRL_D) | (SIGBREAKF_CTRL_E) | (SIGBREAKF_CTRL_F);
  150.  
  151.     /* Wait for next message from the server */
  152.     signals = Wait(signals);
  153.     
  154.     if (signals & (1L << session->qMsgPort->mp_SigBit))
  155.     {
  156.       BOOL BDie = FALSE;
  157.       
  158.       while(qMsg = (struct QMessage *) GetMsg(session->qMsgPort))
  159.       {
  160.         if (qMsg->qm_Status != QERROR_NO_ERROR) 
  161.         {
  162.           printf("-->Error %i detected, exiting!\n", qMsg->qm_Status);
  163.           BDie = TRUE;
  164.         }
  165.         else
  166.         {
  167.           char * name = qMsg->qm_Path ? (GetNthPart(qMsg->qm_Path, 2)+sizeof("mini_irc_")-1) : "<unknown?>";
  168.           char * data = (char *) qMsg->qm_Data;
  169.           int id      = qMsg->qm_ID;
  170.                     
  171.                if ((id == clientOp))         printf("%s has just %s the room.\n", name, qMsg->qm_Data?"entered":"left");
  172.           else if ((id == actionOp)&&(data)) printf("%s %s.\n", name, data);
  173.           else if ((id == talkOp)&&(data))   printf("%s: %s\n", name, data);
  174.         }
  175.         FreeQMessage(session,qMsg);
  176.       }
  177.       if (BDie) break;
  178.     }
  179.     if (signals & SIGBREAKF_CTRL_C) break;
  180.     if (signals & SIGBREAKF_CTRL_D)
  181.     {
  182.       char buf[900];
  183.         
  184.       printf("==> Enter your action: "); fflush(stdout);
  185.       gets(buf);
  186.       UNLESS((QSetOp(session, "action", buf, strlen(buf)+1))&&(QGo(session, 0L)))
  187.         printf("-->Error sending your action!\n");
  188.     }
  189.     if ((signals & SIGBREAKF_CTRL_E)&&(ListPeopleInRoom() == FALSE)) break;
  190.     if (signals & SIGBREAKF_CTRL_F)
  191.     {
  192.       char buf[900];
  193.         
  194.       printf("==> Enter your message: "); fflush(stdout);
  195.       gets(buf);
  196.       UNLESS((QSetOp(session, "talk", buf, strlen(buf)+1))&&(QGo(session, 0L)))
  197.         printf("-->Error sending your line!\n");
  198.     }
  199.   }
  200.   
  201.   /* Note: CleanExit() is called here, via the atexit() function! */
  202. }